package com.sam.im.heiqun.utils;

import android.app.Dialog;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.util.Log;

import com.google.zxing.Result;
import com.sam.im.heiqun.entities.beans.DownloadInfo;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Cancellable;
import io.reactivex.schedulers.Schedulers;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;

/**
 * Created by zhangqiang on 2018/5/29.
 */
public class RxJavaUtil {

    public static <T> ObservableTransformer<T, T> applySchedules() {

        return new ObservableTransformer<T, T>() {
            @Override
            public ObservableSource<T> apply(Observable<T> upstream) {

                return upstream.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread());
            }
        };
    }


    public static <T> ObservableTransformer<T, T> bindDialogDismissLifeCycle(final Dialog dialog) {

        return new ObservableTransformer<T, T>() {
            @Override
            public ObservableSource<T> apply(Observable<T> upstream) {
                return upstream.takeUntil(Observable.create(new ObservableOnSubscribe<Boolean>() {
                    @Override
                    public void subscribe(final ObservableEmitter<Boolean> e) throws Exception {
                        dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
                            @Override
                            public void onDismiss(DialogInterface dialog) {
                                e.onNext(true);
                                e.onComplete();
                            }
                        });
                        e.setCancellable(new Cancellable() {
                            @Override
                            public void cancel() throws Exception {
                                dialog.setOnDismissListener(null);
                            }
                        });
                    }
                }));
            }
        };
    }

    /**
     * 解析二维码
     *
     * @param bitmap
     * @return
     */
    public static Observable<String> decodeQrCode(final Bitmap bitmap) {

        return Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> e) {

                try {

                    Result result = BitmapUtils.decodeQrCode(bitmap);
                    if (result != null) {
                        e.onNext(result.getText());
                    }
                } catch (Throwable throwable) {

                    e.onError(throwable);
                } finally {
                    e.onComplete();
                }
            }
        });
    }

    /**
     * 下载文件
     *
     * @param url
     * @param saveFile
     * @return
     */
    public static Observable<DownloadInfo> download(final String url, final File saveFile) {

        return Observable.create(new ObservableOnSubscribe<DownloadInfo>() {
            @Override
            public void subscribe(ObservableEmitter<DownloadInfo> e) throws Exception {
                InputStream inputStream = null;
                OutputStream outputStream = null;

                try {

                    outputStream = new FileOutputStream(saveFile);

                    Request request = new Request.Builder()
                            .url(url)
                            .get()
                            .build();
                    Response response = OKHttpUtil.getOkHttpClient().newCall(request).execute();
                    if (response == null) {
                        e.onError(new RuntimeException("response Null"));
                        return;
                    }
                    ResponseBody body = response.body();
                    if (body == null) {
                        e.onError(new RuntimeException("response body Null"));
                        return;
                    }
                    long contentLength = body.contentLength();
                    long downloadLength = 0;
                    long lastComputeLength = 0;
                    long lastComputeTime = System.currentTimeMillis();
                    inputStream = body.byteStream();
                    byte[] buffer = new byte[1024];
                    int len;

                    while ((len = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, len);
                        downloadLength += len;
                        long currentTime = System.currentTimeMillis();
                        if (currentTime - lastComputeTime > 2 * 1000 && downloadLength - lastComputeLength > 10 * 1024) {
                            lastComputeLength = downloadLength;
                            lastComputeTime = currentTime;
                            DownloadInfo info = new DownloadInfo(false, contentLength, downloadLength);
                            e.onNext(info);
                            Log.i("Test","======downloading...=====" + info.toString());
                        }
                    }
                    outputStream.flush();
                    e.onNext(new DownloadInfo(true, contentLength, downloadLength));
                }catch (InterruptedIOException interrupt){
                    interrupt.printStackTrace();
                }finally {
                    e.onComplete();
                    IoUtil.closeSilently(inputStream);
                    IoUtil.closeSilently(outputStream);
                }
            }
        });
    }
}
